<html>
	<head>
		<meta charset="UTF-8" />
		<!-- import CSS -->
		<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
		<title>股票小工具</title>
		<link href="../static/images/stock.ico" type="image/x-icon" rel="shortcut icon" />
	</head>
	<body>
		<div id="app">
			<!-- 普通字符串加密取 -->
			<el-row :gutter="10">
				<el-card class="box-card">
					<div slot="header" class="clearfix">
						<el-form :inline="true" :model="stockForm" style="height: 25px;" size="large">
							<el-form-item label="交易日期:">
								<el-col :span="11">
									<el-date-picker v-model="stockForm.date1" type="date" placeholder="开始日期"
										style="width: 100%" />
								</el-col>
								<el-col :span="2" class="text-center">
									<span class="text-gray-500">—</span>
								</el-col>
								<el-col :span="11">
									<el-date-picker v-model="stockForm.date2" type="date" placeholder="结束日期"
										style="width: 100%" />
								</el-col>
							</el-form-item>
							<el-form-item label="股票代码:">
								<el-input v-model="stockForm.code" placeholder="股票代码" clearable
									style="width: 250px;" />
							</el-form-item>
							<el-form-item>
								<el-button type="primary" v-if="stockForm.code"
									@click="stockFormSubmit('stockForm')">确定</el-button>
								<el-tooltip class="item" v-else effect="light" content="请填写股票代码!">
									<el-button type="danger">确定</el-button>
								</el-tooltip>
							</el-form-item>
							<!-- <el-form-item  style="float: right; padding: 3px 0"> -->
							<el-form-item>
								<el-button type="success" v-if="stockForm.code" @click="downloadStock">保存数据
									<el-tooltip class="item" effect="light" content="默认保存在同级目录【股票数据】文件夹下!">
										<i class="el-icon-info"></i>
									</el-tooltip>
								</el-button>
								<el-tooltip class="item" v-else effect="light" content="请填写股票代码!">
									<el-button type="danger">保存数据
										<el-tooltip class="item" effect="light" content="默认保存在同级目录【股票数据】文件夹下!">
											<i class="el-icon-info"></i>
										</el-tooltip>
									</el-button>
								</el-tooltip>
							</el-form-item>

							<el-dropdown style="float: right;">
								<el-button type="primary">
									配置<i class="el-icon-arrow-down el-icon--right"></i>
								</el-button>
								<el-dropdown-menu slot="dropdown">
									<el-dropdown-item style="text-align:center">
										<el-button type="text" @click="open">修改TOKEN</el-button>
									</el-dropdown-item>
									<el-dropdown-item style="text-align:center">
										<el-button type="text" @click="resetToken">重置TOKEN</el-button>
									</el-dropdown-item>
									<!-- <el-dropdown-item style="text-align:center">配置2</el-dropdown-item>
									<el-dropdown-item style="text-align:center">配置3</el-dropdown-item>
									<el-dropdown-item style="text-align:center">配置4</el-dropdown-item> -->
								</el-dropdown-menu>
							</el-dropdown>
					</div>

					<el-row>
						<el-tabs v-model="activeName" type="card">
							<el-tab-pane label="可视化" name="first">
								<div id="main" style="width:auto;height:520px;"></div>
							</el-tab-pane>
							<el-tab-pane label="数据预览" name="second">
								<el-table :data="tableData" height="520px" border style="width: 100%"
									:default-sort="{prop: '交易日期', order: 'descending'}">
									<el-table-column v-for="i in tableColumns" :prop="i" :label="i" align="center"
										sortable>
									</el-table-column>
								</el-table>
							</el-tab-pane>
						</el-tabs>
					</el-row>
				</el-card>
			</el-row>
		</div>
	</body>
	<!-- 导入下载的 echarts.min.js -->
	<script src="../static/js/echarts.min.js"></script>
	<!-- import Vue before Element -->
	<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
	<!--<script src="https://unpkg.com/vue/dist/vue.js"></script>-->
	<!-- import JavaScript -->
	<script src="https://unpkg.com/element-ui/lib/index.js"></script>
	<!--导入 axios 获取数据-->
	<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
	<script>
		const upColor = "#ec0000"
		const upBorderColor = "#8A0000"
		const downColor = "#00da3c"
		const downBorderColor = "#008F28"

		var nv = new Vue({
			el: '#app',
			delimiters: ['[{', '}]'],
			data: function() {
				return {
					// 表单数据
					stockForm: {
						date1: "",
						code: '000001',
						date2: ""
					},
					// 图表数据
					kChartdata: null,
					// 预测信息
					forcastMsg: "预测信息",
					// 股票名
					stockName: "",
					activeName: 'first',
					tableColumns: null,
					tableData: null,
				}
			},
			created: function() {
				this.stockFormSubmit()
			},
			methods: {
				async resetToken() {
					const {
						data: res
					} = await this.$http.post("/token", {
						"token": "reset"
					})
					if (res.status == 200) {
						this.$message({
							showClose: true,
							type: 'success',
							message: res.msg
						})
					} else {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'error',
							duration: 10000
						})
					}
				},
				open() {
					this.$prompt(
						'<a href="https://tushare.pro/register?reg=591167" target="_blank" style="color: #007bff;text-decoration: none;">点击获取【TOKEN】</a>',
						'修改TOKEN', {
							dangerouslyUseHTMLString: true,
							confirmButtonText: '确定',
							cancelButtonText: '取消',
							inputPattern: /^[0-9a-zA-Z]*$/,
							inputErrorMessage: 'token只能由字母和数字组成！'
						}).then(({
						value
					}) => {
						if (value) {
							this.postToken(value)
						} else {
							this.$message({
								showClose: true,
								type: 'info',
								message: '取消输入'
							});
						}

					}).catch(() => {
						this.$message({
							showClose: true,
							type: 'info',
							message: '取消输入'
						});
					});
				},
				async postToken(token) {
					const {
						data: res
					} = await this.$http.post("/token", {
						"token": token
					})
					if (res.status == 200) {
						this.$message({
							showClose: true,
							type: 'success',
							message: 'token保存成功！'
						})
					} else {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'error',
							duration: 10000
						})
					}
				},
				// 下载数据
				async downloadStock() {
					const {
						data: res
					} = await this.$http.post("/download", this.stockForm)
					if (res.status != 200) {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'error',
							duration: 10000
						})
					} else {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'success',
							duration: 15000
						})
					}
				},
				// 获取输入的股票代码数据
				async stockFormSubmit(stockForm) {
					const {
						data: res
					} = await this.$http.post("/stock", this.stockForm)
					if (res.status != 200) {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'error',
							duration: 10000
						})
					} else {
						this.$message({
							showClose: true,
							message: res.msg,
							center: true,
							type: 'success'
						})
						// 重新赋值新的股票数据
						var myChart = echarts.init(document.getElementById('main'))
						this.kChartdata = res.stock_data
						this.forcastMsg = this.kChartdata.forcast
						this.stockName = this.kChartdata.ts_name
						this.tableColumns = this.kChartdata.table_columns
						this.tableData = this.kChartdata.table_data
						var option = {
							// 图表标题配置
							title: {
								text: '【'+this.stockName+'】' + 'K线图'
							},
							// 提示框配置
							tooltip: {
								// 是否显示提示框
								show: true,
								// 触发类型，axis 移动到坐标轴就触发
								trigger: "axis",
								// 坐标轴上提示点设置
								axisPointer: {
									type: "cross"
								}
							},
							// 图例配置
							legend: {
								data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']
							},
							// X 轴配置项
							xAxis: {
								type: "category",
								data: this.kChartdata.stock_trade_days,
								boundaryGap: false,
								axisLine: {
									onZero: false
								},
								splitLine: {
									show: true
								},
								min: "dataMin",
								max: "dataMax"
							},
							// y 轴配置项
							yAxis: {
								scale: true,
								splitArea: {
									show: true
								}
							},
							dataZoom: [{
									type: "inside",
									start: 50,
									end: 100
								},
								{
									show: true,
									type: "slider",
									top: "90%",
									start: 50,
									end: 100
								}
							],
							// 系列配置，根据不同图表有不同的配置
							series: [{
									name: "日K",
									// 图表类型
									type: 'candlestick',
									// 数据内容
									data: this.kChartdata.stock_trade_data,
									// K 线图的图形样式
									itemStyle: {
										// 阳线 图形的颜色
										color: upColor,
										// 阴线 图形的颜色。
										color0: downColor,
										// 阳线 图形的描边颜色
										borderColor: upBorderColor,
										// 阴线 图形的描边颜色
										borderVolor0: downBorderColor
									},
									// 标记点配置
									markPoint: {
										// 标注的文本
										label: {
											// 标签内容格式器，支持字符串模板和回调函数两种形式，字符串模板与回调函数返回的字符串均支持用 \n 换行。
											// 参数 params 是 formatter 需要的单个数据集, value是传入的数据值。
											formatter: function(param) {
												return param != null ? Math.round(param.value) + "" :
													"";
											}
										},
										// 标注的数据数组。每个数组项是一个对象
										data: [
											// 特殊的标注类型，用于标注最大值最小值等
											{
												name: "highest value",
												type: "max",
												// 在使用 type 时有效，用于指定在哪个维度上指定最大值最小值。
												valueDim: "highest",
											},
											{
												name: 'lowest value',
												type: 'min',
												valueDim: 'lowest'
											},
											{
												name: 'average value on close',
												type: 'average',
												valueDim: 'close'
											}
										],
										// 提示框浮层内容格式器，支持字符串模板和回调函数两种形式。
										tooltip: {
											// params 是 formatter 需要的数据集
											formatter: function(param) {
												// name数据名，类目名,data传入的原始数据项
												return param.name + "<br>" + (param.data.coord || "")
											}
										}
									},
									markLine: {
										// 标线两端的标记类型，可以是一个数组分别指定两端，也可以是单个统一指定
										symbol: ['none', 'none'],
										// 标线的数据数组。每个数组项可以是一个两个值的数组，分别表示线的起点和终点，每一项是一个对象
										data: [
											[
												// 定义从最小值到最大值的线
												{
													name: "from lowest to highest",
													type: "min",
													valueDim: "lowest",
													symbol: "circle",
													symbolSize: 10,
													label: {
														show: false
													},
													emphasis: {
														label: {
															show: false
														}
													}
												},
												{
													type: "max",
													valueDim: "highest",
													symbol: "circle",
													symbolSize: 10,
													label: {
														show: false
													},
													emphasis: {
														label: {
															show: false
														}
													}
												},
											],
											// 最小值水平线
											{
												name: "min line on close",
												type: "min",
												valueDim: "close"
											},
											// 最大值水平线
											{
												name: "max line on close",
												type: "max",
												valueDim: "close"
											},
										],
									}
								},
								{
									name: "MA5",
									type: "line",
									data: this.kChartdata.MA5,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA10",
									type: "line",
									data: this.kChartdata.MA10,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA20",
									type: "line",
									data: this.kChartdata.MA20,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
								{
									name: "MA30",
									type: "line",
									data: this.kChartdata.MA30,
									smooth: true,
									lineStyle: {
										opacity: 0.5
									}
								},
							]
						}
						//使用刚指定的配置项和数据显示图像
						myChart.setOption(option)
					}
				},
			}
		});
	</script>
</html>